package com.dwxt.cdms.service;

import com.dwxt.cdms.api.common.utils.DateUtil;
import com.dwxt.cdms.api.common.utils.StringUtil;
import com.dwxt.cdms.base.Page;
import com.dwxt.cdms.constant.TaskMessageData;
import com.dwxt.cdms.dao.MedicationRemindMapper;
import com.dwxt.cdms.entity.MedicationRemind;
import com.dwxt.cdms.entity.MedicationRemindExample;
import com.dwxt.cdms.util.RedisUtil;
import com.dwxt.cdms.util.UUIDUtil;
import com.dwxt.common.base.BaseResult;
import com.dwxt.common.util.DateUtils;
import com.dwxt.common.util.PartyUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;

@Service
@Slf4j
public class MedicationRemindService {

    @Autowired
    private MedicationRemindMapper medicationRemindMapper;

    @Autowired
    private LbWatchService lbWatchService;
    @Autowired
    private EquipmentCustomService equipmentCustomService;


    public BaseResult page(Page page, MedicationRemind medicationRemind) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        MedicationRemindExample example = new MedicationRemindExample();
        example.createCriteria().andCustomerIdEqualTo(medicationRemind.getCustomerId());
        example.setOrderByClause("create_time desc");
        List<MedicationRemind> medicationRemindList = medicationRemindMapper.selectByExample(example);
        PageInfo pageInfo = new PageInfo(medicationRemindList);
        return BaseResult.ok(pageInfo);
    }

    public List<MedicationRemind> list() {
        MedicationRemindExample example = new MedicationRemindExample();
        List<MedicationRemind> medicationRemindList = medicationRemindMapper.selectByExample(example);
        return medicationRemindList;
    }

    public BaseResult add(MedicationRemind medicationRemind) {
        String currentUserId = "";
        try {
            currentUserId = PartyUtil.getCurrentUserId();
        } catch (Exception e) {
            currentUserId = medicationRemind.getCustomerId().toString();
        }
        String lbUserId = equipmentCustomService.selectLbUseridByCustomerId(medicationRemind.getCustomerId());
        String taskId = "";
        if (StringUtil.isBlank(medicationRemind.getId())) {
            // 新增
            medicationRemind.setCreateUser(Integer.valueOf(currentUserId));
            medicationRemind.setId(UUIDUtil.getUUID());
            if (StringUtil.isNotBlank(lbUserId)) {
                taskId = lbWatchService.addRemind(lbUserId, medicationRemind.getHour(), medicationRemind.getMinute());
                medicationRemind.setTaskid(taskId);
            }
            medicationRemindMapper.insertSelective(medicationRemind);

        } else {
            // 修改
            MedicationRemind oldRemind = medicationRemindMapper.selectByPrimaryKey(medicationRemind.getId());
            // 判断是否有来邦设备，设置来邦的用药提醒
            if (StringUtil.isNotBlank(lbUserId)) {
                if (oldRemind.getStatus() == 0 && medicationRemind.getStatus() == 0) {
                    //off ->  off
                }else if (oldRemind.getStatus() == 0 && medicationRemind.getStatus() == 1) {
                    //off ->  on
                    String taskIdStr = lbWatchService.addRemind(lbUserId, medicationRemind.getHour(), medicationRemind.getMinute());
                    medicationRemind.setTaskid(taskIdStr);
                }else if (oldRemind.getStatus() == 1 && medicationRemind.getStatus() == 1) {
                    //on ->  on
                    lbWatchService.updateRemind(lbUserId,oldRemind.getTaskid(),medicationRemind.getHour(),medicationRemind.getMinute());
                }else if (oldRemind.getStatus() == 1 && medicationRemind.getStatus() == 0) {
                    //on ->  off
                    lbWatchService.deleteRemind(lbUserId,oldRemind.getTaskid());
                    medicationRemind.setTaskid("");
                }

            }
            medicationRemind.setUpdateUser(Integer.valueOf(currentUserId));
            medicationRemindMapper.updateByPrimaryKeySelective(medicationRemind);
        }
        setRedisValue(medicationRemind);
        return BaseResult.ok();
    }

    public BaseResult delete(String id) {
        MedicationRemind medicationRemind = medicationRemindMapper.selectByPrimaryKey(id);
        String lbUserId = equipmentCustomService.selectLbUseridByCustomerId(medicationRemind.getCustomerId());
        if (StringUtil.isNotBlank(lbUserId)&&StringUtil.isNotBlank(medicationRemind.getTaskid())) {
            lbWatchService.deleteRemind(lbUserId,medicationRemind.getTaskid());
        }
        medicationRemindMapper.deleteByPrimaryKey(id);
        return BaseResult.ok();
    }

    public MedicationRemind selectById(String id) {
        return medicationRemindMapper.selectByPrimaryKey(id);

    }

    /**
     * @param medicationRemind:
     * @return void
     * @Description: 用药提醒计算下次提醒时间并设置到redis中
     * @author chendq
     * @date 2021/10/28
     */
    public void setRedisValue(MedicationRemind medicationRemind) {

        RedisUtil.del(medicationRemind.getId());
        Date nowDate = new Date();
        //开启状态才设置
        if (1==medicationRemind.getStatus()) {
            Long daySecond = getDayTime(medicationRemind);
            //时间内
            RedisUtil.set(medicationRemind.getId(), medicationRemind, daySecond);
        }

    }

    //原用药提醒
    /*public void setRedisValue(MedicationRemind medicationRemind) {
        try {
            RedisUtil.del(medicationRemind.getId());
            Date nowDate = new Date();
            Date startTime = medicationRemind.getStartTime();
            Date endTime = medicationRemind.getEndTime();
            //开启状态才设置
            if ("1".equals(medicationRemind.getStatus().toString())) {
                String timeType = medicationRemind.getTimeType();
                if ("0".equals(timeType)) {
                    //单次定时
                    Date date = DateUtil.parseToDate(medicationRemind.getTime(), DateUtil.FMT_YYYYMMDD_HHMMSS);
                    long l = date.getTime() - nowDate.getTime();
                    if (l>0) {
                        RedisUtil.set(medicationRemind.getId(),medicationRemind,l/1000);
                    }
                } else if ("1".equals(timeType)) {
                    //每天
                    if (StringUtil.isNotBlank(medicationRemind.getTime())) {
                        List<String> hmsList = Arrays.asList(medicationRemind.getTime().split("、"));
                        String ymd = DateUtils.formatDate(nowDate);
                        List<Date> dateList = hmsList.stream().map(s1 -> {
                            String dateStr = ymd + " " + s1;
                            try {
                                return DateUtil.parseToDate(dateStr, DateUtil.FMT_YYYYMMDD_HHMM);
                            } catch (ParseException e) {
                                e.printStackTrace();
                                return null;
                            }
                            //return DateUtils.formatTime(dateStr);
                        }).sorted(Date::compareTo).collect(Collectors.toList());
                        Long daySecond = getDayTime(dateList);
                        long time = new Date(nowDate.getTime() + daySecond * 1000).getTime();
                        //还没到开始时间,就设置开始时间的第一个时间
                        if (time < startTime.getTime()) {
                            String dateStr = DateUtil.parseStr(startTime, DateUtil.FMT_YYYYMMDD) + " " + dateList.get(0);
                            Date date = DateUtil.parseToDate(dateStr, DateUtil.FMT_YYYYMMDD_HHMMSS);
                            RedisUtil.set(medicationRemind.getId(),medicationRemind,(date.getTime()-nowDate.getTime())/1000);
                        } else if (time >= startTime.getTime() && time <= endTime.getTime()) {
                            //时间内
                            RedisUtil.set(medicationRemind.getId(),medicationRemind,daySecond);
                        }
                    }
                } else if ("2".equals(timeType)) {
                    //指定多选星期几
                    if (StringUtil.isNotBlank(medicationRemind.getWeek())&&StringUtil.isNotBlank(medicationRemind.getTime())) {
                        List<String> weekList = Arrays.asList(medicationRemind.getWeek().split("、"));
                        List<String> hmsList = Arrays.asList(medicationRemind.getTime().split("、"));
                        Long weekSecond = getWeekDayTime(hmsList, weekList);
                        long time = new Date(nowDate.getTime() + weekSecond * 1000).getTime();
                        //还没到开始时间,就设置开始时间的第一个时间
                        if (time < startTime.getTime()) {
                            String ymd = DateUtils.formatDate(nowDate);
                            List<Date> dateList = hmsList.stream().map(s1 -> {
                                String dateStr = ymd + " " + s1;
                                return DateUtils.formatTime(dateStr);
                            }).sorted(Date::compareTo).collect(Collectors.toList());
                            String dateStr = DateUtil.parseStr(startTime, DateUtil.FMT_YYYYMMDD) + " " + dateList.get(0);
                            Date date = DateUtil.parseToDate(dateStr, DateUtil.FMT_YYYYMMDD_HHMMSS);
                            RedisUtil.set(medicationRemind.getId(),medicationRemind,(date.getTime()-nowDate.getTime())/1000);
                        } else if (time >= startTime.getTime() && time <= endTime.getTime()) {
                            RedisUtil.set(medicationRemind.getId(),medicationRemind,weekSecond);
                        }
                    }
                }
            }
        } catch (ParseException e) {
            log.error("用药提醒设置任务失败，时间转换异常");
        }
    }*/

    private Long getWeekDayTime(List<String> hmsList, List<String> weekDayList) {
        ArrayList<Long> list = new ArrayList<>();
        for (String weekdayStr : weekDayList) {
            for (String hmsStr : hmsList) {
                System.out.println(weekdayStr + " " + hmsStr);
                Long weekTime = getWeekTime(weekdayStr, hmsStr);
                list.add(weekTime);
            }
        }
        Collections.sort(list);
        return list.get(0);
    }

    public Long getWeekTime(String weekStr, String hms) {
        try {
            Date nowDate = new Date();
            int weekDay = TaskMessageData.getWeekDay(weekStr);
            Calendar cal = Calendar.getInstance();
            cal.setTime(nowDate);
            int nowWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
            if (nowWeek > weekDay) {//已过
                String ymd = TaskMessageData.getNextWeek(weekDay);
                long time = DateUtil.parseToDate(ymd + " " + hms, "yyyy-MM-dd HH:mm").getTime();
                return (time - nowDate.getTime()) / 1000;
            } else if (nowWeek < weekDay) {//还没到
                String ymd = TaskMessageData.getNowWeek(weekDay);
                long time = DateUtil.parseToDate(ymd + " " + hms, "yyyy-MM-dd HH:mm").getTime();
                return (time - nowDate.getTime()) / 1000;
            } else {//当天
                String todayStr = DateUtils.formatDate(nowDate) + " " + hms;
                Date date = DateUtil.parseToDate(todayStr, "yyyy-MM-dd HH:mm");
                long l = date.getTime() - nowDate.getTime();
                if (l > 0) {//今天还没到
                    return l / 1000;
                } else {//今天已经过了,那就下周的今天
                    long nextWeekDayTime = date.getTime() + (7 * 86400000L);
                    return (nextWeekDayTime - nowDate.getTime()) / 1000;
                }
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Long getDayTime(List<Date> dateList) {
        Date now = new Date();
        boolean isToday = dateList.stream().anyMatch(date -> date.getTime() > now.getTime());
        if (!isToday) {
            //今天所有时间已过,获取明天的时间
            //System.out.println("today is over");
            Long time = dateList.get(0).getTime() + 24 * 3600 * 1000;
            //System.out.println(new Date(time));
            return (time - now.getTime()) / 1000;
        }
        for (Date date : dateList) {
            if (date.getTime() - now.getTime() > 0) {
                //System.out.println("true:"+date);
                return (date.getTime() - now.getTime()) / 1000;
            }
        }
        return null;
    }

    public Long getDayTime(MedicationRemind remind) {
        try {
            Date now = new Date();
            String ymd = DateUtils.formatDate(now);
            String dateStr = ymd + " " + remind.getHour() + ":" + remind.getMinute() + ":00";
            Date date = DateUtil.parseToDate(dateStr, DateUtil.FMT_YYYYMMDD_HHMMSS);
            boolean isToday = date.getTime() > now.getTime();
            if (!isToday) {
                //今天所有时间已过,获取明天的时间
                //System.out.println("today is over");
                Long time = date.getTime() + 24 * 3600 * 1000;
                //System.out.println(new Date(time));
                return (time - now.getTime()) / 1000;
            } else {
                return (date.getTime() - now.getTime()) / 1000;
            }
        } catch (ParseException e) {
            log.error("用药提醒时间转换异常");
            return null;
        }
    }

}
